package com.sdhs.paas.flux.app;

import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.sdhs.paas.flux.model.User;

import io.netty.util.internal.ThreadLocalRandom;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;

import org.assertj.core.groups.Tuple;
import org.jboss.logging.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
@RequestMapping(value = "flux")
public class FluxController {
	private static final Logger logger = LoggerFactory.getLogger(UserController.class);
	Map<Long, User> users = new HashMap<>();

	@PostConstruct
	public void init() throws Exception {
		users.put(Long.valueOf(1), new User("1", "Jack", "Smith", "20", new Date()));
		users.put(Long.valueOf(2), new User("2", "Peter", "Johnson", "25", new Date()));
	}

	@GetMapping("test1")
	public String fluxtest1() {
		return "fluxtest1";
	}

	/**
	 * 获取所有用户
	 *
	 * @return
	 */
	@GetMapping(value = "/index", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
	public Flux<User> getAll() {
		return Flux.fromIterable(users.entrySet().stream().map(entry -> entry.getValue()).collect(Collectors.toList()));
	}

	/**
	 * 获取单个用户
	 *
	 * @param id
	 * @return
	 */
	@GetMapping("/{id}")
	public Mono<User> getCustomer(@PathVariable Long id) {
		return Mono.justOrEmpty(users.get(id));
	}

	/**
	 * 创建用户
	 *
	 * @param user
	 * @return
	 */
	@PostMapping("/create")
	public Mono<ResponseEntity<String>> postUser(@RequestBody User user) {
		users.put(Long.valueOf(user.getId()), user);
		logger.info("########### POST:" + user);
		return Mono.just(new ResponseEntity<>("Post Successfully!", HttpStatus.CREATED));
	}
	
    /**
     * 修改用户
     *
     * @param id
     * @param user
     * @return
     */
    @PutMapping("/put/{id}")
    public Mono<ResponseEntity<User>> putCustomer(@PathVariable Long id, @RequestBody User user) {
        user.setId(String.valueOf(id));
        users.put(id, user);
        System.out.println("########### PUT:" + user);
        return Mono.just(new ResponseEntity<>(user, HttpStatus.CREATED));
    }
    

    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public Mono<ResponseEntity<String>> deleteMethod(@PathVariable Long id) {
        users.remove(id);
        return Mono.just(new ResponseEntity<>("Delete Successfully!", HttpStatus.ACCEPTED));
    }
    
    @GetMapping("/{abc}/hello")
    public Mono<String> helloWebFlux(@PathVariable("abc") String name,@RequestParam("pwd") String pwd){
    	return Mono.just("welcome to "+name+"/"+pwd);
    }
    
    @GetMapping("/uuid")
    public Mono<String> uuid(){
    	return Mono.just(UUID.randomUUID().toString().replace("-", ""));
    }
    
    @GetMapping("/random")
    public Flux<ServerSentEvent<Integer>> randomnumbers(){
    	return Flux.interval(Duration.ofSeconds(1))
    			.map(seq -> Tuples.of(seq, ThreadLocalRandom.current().nextInt()))
    			.map(data -> ServerSentEvent.<Integer>builder().id(Long.toString(data.getT1()))
    					.event("randow").data(data.getT2()).build()
    					);
    }
    
}
